package cn.itsource.org.service.impl;

import cn.itsource.config.RedisConst;
import cn.itsource.config.RedisService;
import cn.itsource.org.domain.Department;
import cn.itsource.org.mapper.DepartMentMapper;
import cn.itsource.org.query.DepartmentQuery;
import cn.itsource.org.service.IDepartmentService;
import cn.itsource.utils.AjaxResult;
import cn.itsource.utils.PageList;
import cn.itsource.vo.TreeDepartment;
import com.alibaba.fastjson.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.ArrayList;
import java.util.List;

@Service
@Transactional //事务
public class DepartmentServiceImpl implements IDepartmentService {
    @Autowired
    private DepartMentMapper departMentMapper;

    @Override
    public List<Department> loadAll() {
        return departMentMapper.loadAll();
    }

    /*
     * 业务层，处理当前这个操作的所有业务逻辑
     */
    @Override
    public List<Department> findByParams(DepartmentQuery query) {
        /*
            在业务层实现： 带条件的查询
         */
        //1. 处理查询条件可能会前后带空格
//        query.setName(query.getName().trim());
        if (StringUtils.isNotBlank(query.getKeyword())) {
            query.setKeyword(query.getKeyword().trim());
        }

        return departMentMapper.findByParams(query);

    }

    @Override
    public PageList<Department> findPageByParams(DepartmentQuery query) {
        PageList<Department> pageList = new PageList<>();
        //实现分页查询效果
        /*
            实现分页效果，需要后台传回2个数据：
                1.当前查询的这一页的整个数据(分页？)
                2.符合条件的总记录数
         */
        //1.当前查询的这一页的整个数据
        List<Department> list = departMentMapper.findPageByParams(query);
        pageList.setData(list);
        //2.符合条件的总记录数
        Long total = departMentMapper.findPageByParamsCount(query);
        pageList.setTotal(total);
        return pageList;
    }

    @Override
    public AjaxResult bartchDel(List<Long> ids) {
        if (ids == null) {
            return AjaxResult.me().setSuccess(false)
                    .setMessage("删除数据不能为空，至少删除一条数据");
        }
        //完成删除操作
        departMentMapper.bartchDel(ids);
        return AjaxResult.me();
    }


    //使用redis的技术，优化查询效率
    @Autowired
    private RedisService redisService;

    /**
     * 查询出所有部门的列表，同时 每个部门的所有下级，一直递归查询到最后一下级
     */
    @Override
    public List<Department> findTreeDepartment() {
        List<Department> departmentList = null;
         /*
            RedisService工具类的使用：
                注意：如果要保存的是一个集合对象，统一保存为 字符串

                redis优化思路：
                    1.每次查询时，先不要查数据库，先到Redis中找一下，是否有缓存的数据
                    2.如果redis中没有，再查数据库
                    3.查完后，将数据库查出来的数据再保存到redis

                    以后，每次查询，都按上面相同的流程执行

         */
//        //1.先去redis中查
//        String jsonList = redisService.getKeyObjectValue(RedisConst.REDIS_KEY_FINDTREEDEPARTMENT, String.class);
//        //2.如果redis中没有，再查数据库
//        if (StringUtils.isNotBlank(jsonList)){//如果说不为空，说明缓存是存在的，那就不再查数据库了
//            departmentList = JSONArray.parseArray(jsonList, Department.class);
//        }else {
//            //查询出部门的上下级结构树
            departmentList = departMentMapper.findTreeDepartment();
//           // 3.查完后，将数据库查出来的数据再保存到redis
//            redisService.setStringKeyAndValue(RedisConst.REDIS_KEY_FINDTREEDEPARTMENT, JSONArray.toJSONString(departmentList));
//        }

        //重写 遍历这个结果集，然后一个一个的将path的值计算出 parentIds的值

        return departmentList;

//        //将查询出来的结果，重新进行封装，按照自定义的TreeDepartment进行改造
//        List<TreeDepartment> treeList = new ArrayList<>();
//        for (Department department : departmentList) {
//            //首先循环的是第1次(顶级部门）
//            TreeDepartment treeDepartment = new TreeDepartment();
//            treeDepartment.setValue(department.getId()+"");
//            treeDepartment.setLabel(department.getName());
//            if (department.getParent() != null) {
//
//            }
//            treeList.add(treeDepartment);
//        }
//
//        return treeList;
    }

    /*
        这个方法即是新增也是修改
        判断标准：如果主键ID为null，则是新增
        如果主键ID是非null，则是修改

     */
    @Override
    public AjaxResult save(Department dept) {
        //如果说这里要添加校验，是在这里继续添加
        if (StringUtils.isBlank(dept.getSn())) {
            return AjaxResult.me().setSuccess(false).setMessage("部门编号不能为空");
        }
        //调用实体类中的这个方法，就可以统一处理parentId和path的值
        dept.initData();

        //判断id
        if (dept.getId() == null) {//新增
            departMentMapper.save(dept);
        }else {//修改
            departMentMapper.update(dept);
        }

        return AjaxResult.me();

    }
}
